﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
using McTools.Xrm.Connection;
using MetadataDocumentationGenerator.DelegatesHelpers;
using MetadataDocumentationGenerator.Helpers;
using MetadataDocumentationGenerator.Properties;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Metadata;
using System.Drawing;
using MetadataDocumentationGenerator.Dialog;

namespace MetadataDocumentationGenerator.Controls
{
    /// <summary>
    /// User control for entity selection
    /// </summary>
    public partial class Step2 : UserControl, IStepControl
    {
        #region Variables

        private readonly List<EntityMetadata> _entityList;

        /// <summary>
        /// Generation settings
        /// </summary>
        private readonly GenerationSettings _settings;
        
        /// <summary>
        /// IOrganization service
        /// </summary>
        private readonly IOrganizationService _service;

        #endregion Variables

        #region Constructor

        /// <summary>
        /// Initializes a new instance of class Step2
        /// </summary>
        /// <param name="settings">Generation settings</param>
        /// <param name="service">IOrganization service</param>
        /// <param name="entityList"> </param>
        public Step2(GenerationSettings settings, IOrganizationService service, List<EntityMetadata> entityList)
        {
            _settings = settings;
            _service = service;
            _entityList = entityList;

            InitializeComponent();

            FillEntitiesList(entityList);
        }

        #endregion Construction

        #region User Control Handlers

        private void Step2Load(object sender, EventArgs e)
        {
            // Apply existing settings
            rdbAllAttributes.Checked = (_settings.AttributesSelection & AttributeSelectionOption.AllAttributes) == AttributeSelectionOption.AllAttributes;
            rdbAttributesOnForm.Checked = (_settings.AttributesSelection & AttributeSelectionOption.AttributesOnForm) == AttributeSelectionOption.AttributesOnForm;
            rdbOptionSetAttributes.Checked = (_settings.AttributesSelection & AttributeSelectionOption.AttributesOptionSet) == AttributeSelectionOption.AttributesOptionSet;
            rdbSelectAttributes.Checked = (_settings.AttributesSelection & AttributeSelectionOption.AttributeManualySelected) == AttributeSelectionOption.AttributeManualySelected;
        }

        private void LvEntitiesItemChecked(object sender, ItemCheckedEventArgs e)
        {
            if (lvEntities.CheckedItems.Count > 0 && pnlError.Visible)
                pnlError.Visible = false;
        }

        #endregion User Control Handlers

        #region Methods

        void BwFillEntitiesRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                var errorMessage = CrmExceptionHelper.GetErrorMessage(e.Error, true);
                CommonDelegates.DisplayMessageBox(ParentForm, errorMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                if(_settings.EntitiesToProceed != null)
                {
                    foreach (
                        var item in
                            lvEntities.Items.Cast<ListViewItem>().Where(
                                item => _settings.EntitiesToProceed.Exists(x => x.Name == item.SubItems[1].Text)))
                    {
                        item.Checked = true;
                    }
                }
            }
        }

        public void FillEntitiesList(List<EntityMetadata> entities)
        {
            try
            {
                ListViewDelegates.ClearItems(lvEntities);

                foreach (var emd in entities)
                {
                    var item = new ListViewItem
                                   {
                                       Text =
                                           emd.DisplayName != null && emd.DisplayName.UserLocalizedLabel != null
                                               ? emd.DisplayName.UserLocalizedLabel.Label
                                               : "N/A"
                                   };

                    item.SubItems.Add(emd.LogicalName);
                    item.Tag = emd;
                    if (_settings.EntitiesToProceed.Count(t => t.Name == emd.LogicalName) > 0)
                        item.Checked = true;
                    ListViewDelegates.AddItem(lvEntities, item);
                }

                ListViewDelegates.AddColumn(lvEntities, new ColumnHeader { Text = Resources.DisplayNameHeader, Width = 160 });
                ListViewDelegates.AddColumn(lvEntities, new ColumnHeader { Text = Resources.SchemaNameHeader, Width = 130 });
            }
            catch (Exception error)
            {
                var errorMessage = CrmExceptionHelper.GetErrorMessage(error, true);
                CommonDelegates.DisplayMessageBox(ParentForm, errorMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        public GenerationSettings GetSettings()
        {
            if (lvEntities.CheckedItems.Count == 0)
            {
                pnlError.Visible = true;
                return null;
            }

            _settings.EntitiesToProceed = new List<EntityItem>();

            foreach (ListViewItem item in lvEntities.CheckedItems)
            {
                var emd = (EntityMetadata) item.Tag;

                _settings.EntitiesToProceed.Add(new EntityItem {Name = emd.LogicalName, Attributes = new List<string>()});

            }

            var loadingForm = new EntityLoad(_entityList, _settings.EntitiesToProceed, _service);
            loadingForm.ShowDialog(this);

            _settings.AttributesSelection = rdbAllAttributes.Checked
                                                ? AttributeSelectionOption.AllAttributes
                                                : rdbAttributesOnForm.Checked
                                                      ? AttributeSelectionOption.AttributesOnForm
                                                      : rdbOptionSetAttributes.Checked
                                                            ? AttributeSelectionOption.AttributesOptionSet
                                                            : AttributeSelectionOption.AttributeManualySelected;

            return _settings;
        }

        #endregion Methods
    }
}
